package clientAPI;
import java.io.Serializable;
import java.util.Date;
import java.lang.Math;


/**
 * ClientMessage is an object containing directions on what the robot should do.
 * @author Jonathan
 *
 */
public class ClientMessage implements Serializable { 
	private static final long serialVersionUID = 1L;
	Drive D;
	Turn T;
	
	/** This variable is set to the number of degrees the robot should turn. Positive = clockwise.*/
	private int turn;
	/** This variable is set to the number of centimetres the robot should drive. Negative means backwards. */
	private int drive;
	/** If this variable is true, the server will terminate the connection. */
	private Boolean terminate;
	
	private Boolean automatic;
	
	private int scans;
	
	/** This variable is used to add additional information. If a message need send
	 * more information than available to the server, this field can be used. If
	 * this needs to be done often in a similar manner, a new field can be added to
	 * the API. This should prevent the API being changed too frequently.
	 */
	private String additional;
	/** A time stamp saying when the message was created. */
	private Date date;
	
	
	/** This function is used to add additional information the package.
	 * @param str The actual message.
	 * */
	void additionalInfo(String str){
		additional = str;
	}
	/**
	 * This function is used, if the message should flag for connection termination.
	 * There is no reason to use this function to set the value to false, as this is
	 * the default value.
	 * @param term true means terminate, false is default. 
	 */
	public void setTerminate(Boolean term) {
		terminate = term;
	}
	
	public int getNumScans() {
		return scans;
	}
	
	public boolean automatic() {
		return automatic;
	}
	
	/**
	 * The message constructor. Note that there is an "additional" field that
	 * can be used, which is set using additionalInfo().
	 * @param t The number of degrees to turn. Positive = clockwise
	 * @param d The number of centimeters to drive. Negative backwards.
	 */
	public ClientMessage(int t, int d, int scans){
		turn = t; drive = d;
		this.scans = scans;
		terminate = false;
		D = null; T = null;
		date= new java.util.Date();
		automatic = false;
	}
	
	public ClientMessage(Turn t, Drive d) {
		T = t;
		D = d;
		turn = 0; drive = 0; terminate = false;
		date = new java.util.Date();
		automatic = false;
	}
	
	public ClientMessage(boolean automatic) {
		T = null;
		D = null;
		this.automatic = automatic;
		turn = 0; drive = 0; terminate = false;
		date = new java.util.Date();
	}
	
	/**
	 * Used to access the information on if the robot is currently turning
	 * @return The turning direction
	 */
	public Turn getT() { return T; }
	
	/**
	 * Used to access the information on if the robot is currently driving
	 * @return The driving direction
	 */
	public Drive getD() { return D; }
	
	
	/**
	 * Used to access the information on how much to turn
	 * @return The direction to turn
	 */
	public int getRotate() { return turn; }
	/**
	 * Used to access the information on how long to drive
	 * @return The direction to drive
	 */
	public int getMove() { return drive; }
	/**
	 * @return true means terminate
	 */
	public Drive getDrive() { return D; }
	public Turn getTurn() { return T; }
	public Boolean willTerminate() { return terminate; }
	/**
	 * Used to access the additional information
	 * @return A string with additional information. If none, string is empty.
	 */
	public String getAdditionalInformation() { return additional; }
	/**
	 * Used to access the message time stamp.
	 * @return The time stamp.
	 */
	public Date getTimestamp() { return date; }
	
	@Override public String toString() {
	    StringBuilder result = new StringBuilder();
	    result.append(this.getClass().getName() + " (" + date + "): ");
	    if (terminate) {
	    	result.append("TERMINATE\n");
	    	return result.toString();
	    }
	    result.append("Drive " + Math.abs(drive) + "cm");
	    if (drive >= 0)
	    	result.append("forwards. ");
	    else
	    	result.append("backwards. ");
	    result.append("Turn " + Math.abs(turn) + "degrees");
	    if (drive >= 0)
	    	result.append("clockwise.");
	    else
	    	result.append("anti-clockwise.");
	   
	    if (additional != "") {
	    	result.append("Additionally: " + additional);
	    }
	    return result.toString();
	}	
}
